<?php
#捕获Warring错误
set_error_handler('displayErrorHandler');
function displayErrorHandler($errno, $errstr, $filename, $line)
{
    $error_no_arr = [
        1    => 'ERROR',
        2    => 'WARNING',
        4    => 'PARSE',
        8    => 'NOTICE',
        16   => 'CORE_ERROR',
        32   => 'CORE_WARNING',
        64   => 'COMPILE_ERROR',
        128  => 'COMPILE_WARNING',
        256  => 'USER_ERROR',
        512  => 'USER_WARNING',
        1024 => 'USER_NOTICE',
        2047 => 'ALL',
        2048 => 'STRICT'
    ];

    if (in_array($errno, [1, 4])) {
        \Log::out('error', 'I', "File:{$filename} on Line:{$line} \n" . $error_no_arr[$errno] . ":" . $errstr . "\n");
        #throw new \Exception($error_no_arr[$errno] . ":". $errstr, $errno);
    }
}

function getTrans(Array $deal, callable $func)
{
    $tryTimes = 0;
    while (isset($deal['error_code']) && $deal['error_code'] != '52000') {
        print_r($deal);
        if (++$tryTimes > 3) break;
        if ($deal['error_code'] == '52001' || $deal['error_code'] == '52002' || $deal['error_code'] == '54003') {
            sleep(1);
            $deal = call_user_func($func);
        } else {
            exit;
        }
    }
    $transer = '';
    if (isset($deal['trans_result']) && is_array($deal['trans_result'])) {
        foreach ($deal['trans_result'] as $v1) {
            $transer .= $v1['dst'];
        }
    }
    sleep(1);
    return $transer;
}

function json($vars, $format = 'json', $callback = 'callback')
{
    header("Access-Control-Allow-Origin:*");
    header("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS,DELETE");
    header("Access-Control-Allow-Headders", "content-type");
    if ($format == 'json') {
        header("Content-type: application/json;charset=utf-8");
        $data = updateNull($vars);
        die(json_encode($data, JSON_UNESCAPED_UNICODE));
    } else {
        header("Content-type: text/javascript;charset=utf-8");
        $data = updateNull($vars);
        die("{$callback}(" . json_encode($data, JSON_UNESCAPED_UNICODE) . ")");
    }
}

function ret($ret = 0, $msg = 'ok', $data = [])
{
    $ret = [
        'ret' => $ret,
        'msg' => $msg,
    ];
    if (!empty($data)) {
        $ret['data'] = $data;
    }
    json($ret);
}

function updateNull(& $onearr)
{
    if (!empty($onearr) && is_array($onearr)) {
        foreach ($onearr as $k => $v) {
            if (is_array($v)) {
                $onearr[$k] = updateNull($v);
            } else {
                if ($v === NULL) {
                    $onearr[$k] = '';
                }
            }
        }
    }
    return $onearr;
}

/***保存SQL记录到redis***/
function remember($key, $ttl, callable $func)
{
    $cache_enable = getConfig()->redis->enable;
    if ($cache_enable && Cache::exists($key)) {
        return Cache::get($key);
    }
    $rows = call_user_func($func);
    if ($cache_enable) {
        Cache::set($key, $rows, $ttl);
    }
    return $rows;
}

/***遗忘***/
function forget($key)
{
    $cache_enable = getConfig()->redis->enable;
    if ($cache_enable && Cache::exists($key)) {
        Cache::delete($key);
    }
}

/***PHP上传文件到七牛cdn***/
function uploadToCDN($filePath, $cdnfileName)
{
    // 需要填写你的 Access Key 和 Secret Key
    $accessKey = getConfig()->cdn->accessKey;
    $secretKey = getConfig()->cdn->secretKey;

    // 构建鉴权对象
    $auth = new \Qiniu\Auth($accessKey, $secretKey);
    // 要上传的空间
    $bucket = getConfig()->cdn->bucket;

    // 生成上传 Token
    $token = $auth->uploadToken($bucket);

    // 上传到七牛后保存的文件名
    $key = $cdnfileName;

    // 初始化 UploadManager 对象并进行文件的上传
    $uploadMgr = new \Qiniu\Storage\UploadManager;

    // 调用 UploadManager 的 putFile 方法进行文件的上传
    list($ret, $err) = $uploadMgr->putFile($token, $key, $filePath);
    if ($err !== null) {
        return false;
    } else {
        return getConfig()->cdn->url . $ret['key'];
    }
}

function getIp()
{
    if (@$_SERVER["HTTP_X_FORWARDED_FOR"])
        $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
    else if (@$_SERVER["HTTP_CLIENT_IP"])
        $ip = $_SERVER["HTTP_CLIENT_IP"];
    else if (@$_SERVER["REMOTE_ADDR"])
        $ip = $_SERVER["REMOTE_ADDR"];
    else if (@getenv("HTTP_X_FORWARDED_FOR"))
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    else if (@getenv("HTTP_CLIENT_IP"))
        $ip = getenv("HTTP_CLIENT_IP");
    else if (@getenv("REMOTE_ADDR"))
        $ip = getenv("REMOTE_ADDR");
    else
        $ip = "Unknown";
    return $ip;
}

/**
 * PHP生成随机字符串
 * @param Int $length 字符串长度
 * @weburl    url                        学习地址：http://www.ijquery.cn/?p=1027
 * @return string
 */
function randStr($length = 10)
{
    $characters   = '23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

function pick($url, $postData = '')
{
    $row  = parse_url($url);
    $host = $row['host'];
    $port = isset($row['port']) ? $row['port'] : 80;
    $file = $row['path'];
    if (is_array($postData)) {
        $postData = http_build_query($postData);
    }
    $len = strlen($postData);
    $fp  = @fsockopen($host, $port, $errno, $errstr, 10);
    if (!$fp) {
        return "$errstr ($errno)\n";
    } else {
        $receive = '';
        $out     = "POST $file HTTP/1.1\r\n";
        $out     .= "Host: $host\r\n";
        $out     .= "Content-type: application/x-www-form-urlencoded\r\n";
        $out     .= "Connection: Close\r\n";
        $out     .= "Content-Length: $len\r\n\r\n";
        $out     .= $postData;
        fwrite($fp, $out);
        while (!feof($fp)) {
            $receive .= fgets($fp, 128);
        }
        fclose($fp);
        $receive = explode("\r\n\r\n", $receive);
        unset($receive[0]);
        return implode("", $receive);
    }
}

function client($url = '', $postData = [], $proxy = "", $cookies = [], $headers = [])
{
    $row  = parse_url($url);
    $host = $row['host'];
    $port = isset($row['port']) ? $row['port'] : ($row['scheme'] == 'https' ? 443 : 80);
    $file = $row['path'] ?? '/';

    $cli  = new Swoole\Coroutine\Http\Client($host, $port, $row['scheme'] == 'https');
    $conf = ['timeout' => 20];
    if (!empty($proxy)) {
        $proxy                   = str_replace(['http://', 'https://'], '', $proxy);
        $proxy                   = explode(':', $proxy);
        $conf['http_proxy_host'] = $proxy[0];
        $conf['http_proxy_port'] = $proxy[1];
    }
    $cli->set($conf);
    if (!empty($cookies)) {
        $cli->setCookies($cookies);
    }
    $raw_headers = [
        'Host'            => $host,
        'User-Agent'      => 'Chrome/49.0.2587.3',
        'Accept'          => 'text/html,application/xhtml+xml,application/xml',
        'Accept-Encoding' => 'gzip',
    ];
    if (!empty($headers)) {
        array_merge($raw_headers, $headers);
    }
    $cli->setHeaders($raw_headers);
    usleep(rand(600000, 1000000));
    if (empty($postData)) {
        $cli->get($file);
    } else {
        $cli->post($file, $postData);
    }
    $body = $cli->body;
    $cli->close();
    return $body;
}

function http_post_json($url, $jsonStr)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($jsonStr)
        ]
    );
    $response = curl_exec($ch);
    #$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    return $response;
}

/**
 * 加密/解密字符串
 *
 * @param string $string 原始字符串
 * @param string $operation 操作选项: DECODE：解密；其它为加密
 * @param string $key 混淆码
 * @return string     $result    处理后的字符串
 */
function authcode($string, $operation, $key = '')
{
    $authorization = 'changpei0628x9385dbc36c077a2e8bec942dd38';
    $key           = md5($key ? $key : $authorization);
    $key_length    = strlen($key);

    $string        = $operation == 'DECODE' ? base64_decode($string) : substr(md5($string . $key), 0, 8) . $string;
    $string_length = strlen($string);

    $rndkey = $box = [];
    $result = '';

    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($key[$i % $key_length]);
        $box[$i]    = $i;
    }

    for ($j = $i = 0; $i < 256; $i++) {
        $j       = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp     = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }

    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a       = ($a + 1) % 256;
        $j       = ($j + $box[$a]) % 256;
        $tmp     = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result  .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }

    if ($operation == 'DECODE') {
        if (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key), 0, 8)) {
            return substr($result, 8);
        } else {
            return '';
        }
    } else {
        return str_replace('=', '', base64_encode($result));
    }
}

function clean_html($doc)
{
	$noise = [
		"#<!--(.*?)-->#is",
		"#<!\[CDATA\[(.*?)\]\]>#is",
		"#<\s*meta\s+(.*?)>#is",
		"#<\s*link\s+(.*?)>#is",
		"#<\s*script[^>]*[^/]>(.*?)<\s*/\s*script\s*>#is",
		"#<\s*script\s*>(.*?)<\s*/\s*script\s*>#is",
		"#<\s*style[^>]*[^/]>(.*?)<\s*/\s*style\s*>#is",
		"#<\s*style\s*>(.*?)<\s*/\s*style\s*>#is",
		"#<\s*(?:code)[^>]*>(.*?)<\s*/\s*(?:code)\s*>#is",
		"#(<\?)(.*?)(\?>)#s",
		"#(\{\w)(.*?)(\})#s",
	];

	foreach($noise as $v){
		$count = preg_match_all($v, $doc, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
		for ($i=$count-1; $i>=0; --$i)
		{
			$replaceKey = '';
			$doc = substr_replace($doc, $replaceKey, $matches[$i][0][1], strlen($matches[$i][0][0]));
		}
	}
	return preg_replace('#\s+#isu', ' ', $doc);
}